﻿
namespace TheCollectiveNetwork.Web.Services
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Data;
    using System.Data.Objects;
    using System.Linq;
    using System.ServiceModel.DomainServices.EntityFramework;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using System.Xml;
    using TCNDataAccessLayer;
    using TheCollectiveNetwork.Classes.GlobalFunctions;
    using TheCollectiveNetwork.Classes.Security;
        

    [CLSCompliant(false)]   // base type exposes _AppDomain which is not cls-compliant as it begins with an underscore so turn cls compliance off for this class
    [EnableClientAccess()]
    [RequiresAuthentication()]
    [RequiresRole("101")]   // This class is meant to only be accessed by administrators, hence the role restriction
    public class UserManagementService : LinqToEntitiesDomainService<TheCollectiveNetworkEntities>
    {

        //Note: the classes prefixed with DTO are conatined in the DataTransferObjects.cs file in the services folder. 
        
        /* ------------------------------------------------
           --  User management related service functions                                                       
           ------------------------------------------------ */
        
        // Searches for a username
        public IQueryable<DTOAccountsUser> Accounts_Search(string pSearchString)
        {
            string SearchStringFiltered;
            SearchStringFiltered = strfunc.FilteredString(pSearchString);

            if (SearchStringFiltered.Length > 0)
            {
                SearchStringFiltered = @"%" + SearchStringFiltered + @"%";
            }
            
            var query = this.ObjectContext.Users_Search(SearchStringFiltered).AsQueryable()                   
                        .Select(user => new DTOAccountsUser() {User_GUID = user.User_GUID, 
                                                               username = user.username, 
                                                               first_name = user.first_name,
                                                               last_name = user.last_name,
                                                               organisation = user.organisation,
                                                               phone_number = user.phone_number})
                        .OrderBy(dtoau => dtoau.username)
                        .Take(50);
                        
            return query;            
        }

      
        // Gets the accounts user details
        public IQueryable<Accounts_User_Details> Accounts_User_Details_Read(Guid pGuidID)
        {
           
            var query = this.ObjectContext.Accounts_User_Details
                        .Where(p => p.User_GUID.Equals(pGuidID));
            return query;
        }


        // Update routine for Accounts_User_details
        public void UpdateAccounts_User_Details(Accounts_User_Details aud)
        {
            if (aud.EntityState == EntityState.Detached)
            {
                this.ObjectContext.Accounts_User_Details.AttachAsModified(aud, this.ChangeSet.GetOriginal(aud));
            }
        }

        // Insert routine for Accounts_User_details
        public void InsertAccounts_User_Details(Accounts_User_Details aud)
        {
            if (aud.EntityState != EntityState.Added)
            {
                if (aud.EntityState != EntityState.Detached)
                {
                    this.ObjectContext.ObjectStateManager.ChangeObjectState(aud, EntityState.Added);
                }
                else {
                    this.ObjectContext.AddToAccounts_User_Details(aud);
                }
            }
        }

        // Delete routine for Accounts_User_details
        public void DeleteAccounts_User_Details(Accounts_User_Details aud)
        {           
            if (aud.EntityState == EntityState.Detached)
            {
                this.ObjectContext.Accounts_User_Details.AttachAsModified(aud);
            }
            this.ObjectContext.DeleteObject(aud);            
        
        }


        // Gets the username associated with the pGuidID
        public IQueryable<DTOusername> GetAccounts_Username(Guid pGuidID)
        {
            
            var query = this.ObjectContext.Accounts_User.AsQueryable()
                        .Where(user => user.User_GUID.Equals(pGuidID))
                        .Select(user => new DTOusername()
                        {
                            User_GUID = user.User_GUID,
                            username = user.username
                        });
                        

            return query;
        }

        // Delete routine for Accounts_User_details
        
        public void DeleteDTOusername_Delete(DTOusername dtouser)
        {
           ObjectParameter returncode;
           ObjectParameter returnmessage;  
           DTOreturnmessage dtomessage;
           DomainException domainException;
                    
            // Create output parameters
           returncode = new ObjectParameter("returncode", typeof(int));     
           returnmessage = new ObjectParameter("returnmessage", typeof(string));
               
          
            // Perform the delete
            this.ObjectContext.accounts_user_delete_user(dtouser.User_GUID, System.Web.HttpContext.Current.User.Identity.Name, returncode, returnmessage);
                        

           // Get the return code and message
           dtomessage = new DTOreturnmessage();
           dtomessage.returncode = (int)returncode.Value;
           dtomessage.returnmessage = (string)returnmessage.Value;
           
            // Throw an error if the returncode is not zero
           if (dtomessage.returncode > 0)
           {
               domainException = new DomainException(dtomessage.returnmessage, dtomessage.returncode);
               throw domainException;
           }
                                
        }


        /* ------------------------------------------------
          -- Regisation request management service functions                                                          
          ------------------------------------------------ */

        // Reads the list of registration requests
        public IQueryable<DTOAccountsRegisterationRequest> GetAccounts_Registration_Requests()
        {
            var query = this.ObjectContext.Accounts_Registration_Requests.AsQueryable()
                       .Select(user => new DTOAccountsRegisterationRequest()
                       {
                           User_GUID = user.User_GUID,
                           email = user.email,
                           first_name = user.first_name,
                           last_name = user.last_name,
                           organisation = user.organisation,
                           phone_number = user.phone_number,
                           datetimecreated = user.datetimecreated,
                           processing_error = user.processing_error,
                           processing_message = user.processing_message
                       } )
                       .OrderBy(user => user.datetimecreated)
                       .Take(1000);

            return query;
        }

        // Approves a registration request
        [Invoke]
        public String ApproveRegistrationRequest(string pGuidIDListXml)
        {
            ObjectParameter returncode;
            ObjectParameter returnmessage;
            DTOreturnmessage dtomessage;
            DomainException domainException;
            String ReturnMsg;

            // Initialise variables
            ReturnMsg = String.Empty;

            // Create output parameters
            returncode = new ObjectParameter("returncode", typeof(int));
            returnmessage = new ObjectParameter("returnmessage", typeof(string));
            
            
            // Perform the delete
            this.ObjectContext.accounts_registration_approve(pGuidIDListXml, System.Web.HttpContext.Current.User.Identity.Name, returncode, returnmessage);


            // Get the return code and message
            dtomessage = new DTOreturnmessage();
            dtomessage.returncode = (int)returncode.Value;
            dtomessage.returnmessage = (string)returnmessage.Value;

            // Throw an error if the returncode is not zero
            if (dtomessage.returncode > 0)
            {
                domainException = new DomainException(dtomessage.returnmessage, dtomessage.returncode);
                throw domainException;
            }
            else if (dtomessage.returncode == 0)
            {
                ReturnMsg = dtomessage.returnmessage;
            }

            return ReturnMsg;

        }


        // Approves a registration request
        [Invoke]
        public String DeleteRegistrationRequest(string pGuidIDListXml)
        {
            ObjectParameter returncode;
            ObjectParameter returnmessage;
            DTOreturnmessage dtomessage;
            DomainException domainException;
            String ReturnMsg;

            // Initialise variables
            ReturnMsg = String.Empty;

            // Create output parameters
            returncode = new ObjectParameter("returncode", typeof(int));
            returnmessage = new ObjectParameter("returnmessage", typeof(string));


            // Perform the delete
            this.ObjectContext.accounts_registration_delete(pGuidIDListXml, System.Web.HttpContext.Current.User.Identity.Name, returncode, returnmessage);


            // Get the return code and message
            dtomessage = new DTOreturnmessage();
            dtomessage.returncode = (int)returncode.Value;
            dtomessage.returnmessage = (string)returnmessage.Value;

            // Throw an error if the returncode is not zero
            if (dtomessage.returncode > 0)
            {
                domainException = new DomainException(dtomessage.returnmessage, dtomessage.returncode);
                throw domainException;
                
            }
            else if (dtomessage.returncode == 0) 
            {
                ReturnMsg = dtomessage.returnmessage;
            }

            return ReturnMsg;

        }
 
    }
}


